local-serverless-stack 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +4 -3
  2. package/README.md +107 -11
  3. package/dist/server/index.js +2 -0
  4. package/dist/server/index.js.map +1 -1
  5. package/dist/server/routes/secrets.d.ts +3 -0
  6. package/dist/server/routes/secrets.d.ts.map +1 -0
  7. package/dist/server/routes/secrets.js +0 -0
  8. package/dist/server/routes/secrets.js.map +1 -0
  9. package/dist/server/services/secrets-explorer.d.ts +39 -0
  10. package/dist/server/services/secrets-explorer.d.ts.map +1 -0
  11. package/dist/server/services/secrets-explorer.js +105 -0
  12. package/dist/server/services/secrets-explorer.js.map +1 -0
  13. package/dist/ui/assets/{ApisPage-DyjG-weG.js → ApisPage-Dg-fuYQY.js} +1 -1
  14. package/dist/ui/assets/{BucketDetailPage-Bvrk1L6q.js → BucketDetailPage-By9deUkc.js} +1 -1
  15. package/dist/ui/assets/{BucketsPage-KgeLoK6e.js → BucketsPage-idHR6yXh.js} +1 -1
  16. package/dist/ui/assets/{DynamoPage-C8rwaEIi.js → DynamoPage-k8NQGeJ_.js} +1 -1
  17. package/dist/ui/assets/{DynamoTablePage-CN5P5f7S.js → DynamoTablePage-C-LPU3I7.js} +1 -1
  18. package/dist/ui/assets/{LambdaDetailPage-BPhEkF44.js → LambdaDetailPage-D8HVidB_.js} +1 -1
  19. package/dist/ui/assets/{LambdasPage-Dz4wxjVd.js → LambdasPage-B19rwgUM.js} +1 -1
  20. package/dist/ui/assets/{OpenSearchCollectionPage-B3s964oC.js → OpenSearchCollectionPage-Bmc8gI8s.js} +1 -1
  21. package/dist/ui/assets/{OpenSearchPage-0fTJJovd.js → OpenSearchPage-CDFY7dS9.js} +1 -1
  22. package/dist/ui/assets/OverviewPage-CWrXkA8s.js +1 -0
  23. package/dist/ui/assets/{QueueDetailPage-peLph1_v.js → QueueDetailPage-CGcXlOrN.js} +1 -1
  24. package/dist/ui/assets/{QueuesPage-CF9yiBkq.js → QueuesPage-BMU0DBMz.js} +1 -1
  25. package/dist/ui/assets/SecretsPage-Dnkt3P3P.css +1 -0
  26. package/dist/ui/assets/SecretsPage-RgJc26ab.js +1 -0
  27. package/dist/ui/assets/{ServiceDetailPage-ZGLPswmY.js → ServiceDetailPage-BZnTIbac.js} +1 -1
  28. package/dist/ui/assets/{ServicesPage-DsoZBBxo.js → ServicesPage-BJCWxYkd.js} +1 -1
  29. package/dist/ui/assets/_plugin-vue_export-helper-DlAUqK2U.js +1 -0
  30. package/dist/ui/assets/{index-BP9zQ9L-.js → index-DGkmrq2b.js} +9 -9
  31. package/dist/ui/index.html +1 -1
  32. package/package.json +2 -1
  33. package/dist/ui/assets/OverviewPage-B13l71G0.js +0 -1
package/CHANGELOG.md CHANGED
@@ -12,11 +12,12 @@ Two self-engine capabilities that let a project drop LocalStack (and the Docker-
12
12
  ### Added
13
13
  - **Secrets Manager emulator** (`src/server/engine/emulators/secretsmanager/`), served by the self engine over AWS JSON 1.1 under the `secretsmanager` SigV4 scope / `X-Amz-Target`: `CreateSecret`, `GetSecretValue`, `PutSecretValue`, `UpdateSecret`, `DescribeSecret`, `DeleteSecret` (recovery window or `ForceDeleteWithoutRecovery`), `RestoreSecret`, `ListSecrets`, `TagResource`/`UntagResource`, `GetRandomPassword`. Real version staging — a new value promotes to `AWSCURRENT` and demotes the old holder to `AWSPREVIOUS`, and `GetSecretValue` resolves by `VersionStage` or `VersionId`; `SecretString` and `SecretBinary` both round-trip; `ClientRequestToken` gives idempotent create/put; secrets are scoped per region and persist in a catalog (not encrypted locally — `KmsKeyId` is accepted and ignored). Errors carry the names the SDK branches on (`ResourceNotFoundException`, `ResourceExistsException`, `InvalidParameterException`, `InvalidRequestException`). This retires the LocalStack Secrets Manager the self engine previously reached only by proxying through `fallbackEndpoint`. Registered in the router (`secretsmanager` → JSON 1.1), the `/_localstack/health` alias and `healthDetail().services`.
14
14
  - **S3 presigned POST** (browser form upload): the S3 emulator now handles `POST /<bucket>` with `multipart/form-data` — the `key` field (with `${filename}` substitution), `Content-Type`, `success_action_status` (200/201-with-`PostResponse`/204) and `success_action_redirect` (303 with `bucket`/`key`/`etag` appended), plus `x-amz-meta-*` fields as object metadata. The upload stores the object exactly like `PutObject` (content-addressed blob, index entry) and emits an `s3:ObjectCreated:Post` event, so bucket-notification Lambdas fire. Backed by a new dependency-free, byte-accurate multipart parser (`src/server/engine/emulators/s3/multipart.ts`). The POST policy/signature fields are accepted but not verified — the engine never verifies SigV4 either.
15
- - **Full-stack wire conformance tests** (`tests/unit/engine/wire-secretsmanager-s3post.test.ts`): boot the real `SelfEngineBackend` HTTP front door and drive both features exactly as the AWS SDK / a browser would — the integration layer no unit test previously covered, which is the class of gap that let earlier omissions reach users. Plus focused unit suites for the Secrets Manager emulator, the S3 POST handler and the multipart parser.
15
+ - **Secrets Manager tab in the dashboard**: the nav gains a **Secrets** section — a list (name, description, version count, last changed, "deletion scheduled" badge) with a per-secret inspector (ARN, tags, `AWSCURRENT`/`AWSPREVIOUS` staging labels per version) and an explicit **Reveal value** button (a plain list never carries secret material — the value is a separate `GET /api/secrets/:name/value` call). Backed by new `GET /api/secrets`, `GET /api/secrets/:name`, `GET /api/secrets/:name/value` routes and a `SecretsExplorer` service that targets the active engine over the AWS wire (works on the self engine and LocalStack alike); the region selector is honored. New runtime dependency: `@aws-sdk/client-secrets-manager`.
16
+ - **`examples/self-hosted` now showcases both features on the self engine**: `billing-service` gains `GET /attachments/upload-url` (returns a `createPresignedPost` form the browser uploads straight to S3) and `GET /receipts/{id}/signature` (reads an HMAC signing key from Secrets Manager — lazily created via `CreateSecret`/`GetRandomPassword`, read via `GetSecretValue` — to sign a receipt id, the pattern of a service reading a signing key at request time). README documents both flows; the secret appears in the dashboard's Secrets tab.
17
+ - **Full-stack wire conformance tests** (`tests/unit/engine/wire-secretsmanager-s3post.test.ts`): boot the real `SelfEngineBackend` HTTP front door and drive both features exactly as the AWS SDK / a browser would — the integration layer no unit test previously covered, which is the class of gap that let earlier omissions reach users. Plus focused unit suites for the Secrets Manager emulator, the S3 POST handler, the multipart parser, and the `SecretsExplorer` + `/api/secrets` route.
16
18
 
17
19
  ### Known gaps (tracked follow-ups)
18
- - **CloudFormation `AWS::SecretsManager::Secret` is not yet provisioned on registration** — declare-and-forget secrets in `resources:` are not created; create them via the SDK (`CreateSecret`, e.g. in a bootstrap step) for now. Wiring the provisioner (and its `@aws-sdk/client-secrets-manager` dependency) is a follow-up.
19
- - **Examples don't yet exercise transactions, Secrets Manager or presigned POST.** The examples are demos, not the conformance surface — the unit + wire tests above are. Extending an example (the `self-hosted` one, the "drop LocalStack" target) to demonstrate these is a follow-up.
20
+ - **CloudFormation `AWS::SecretsManager::Secret` is not yet provisioned on registration** — declare-and-forget secrets in `resources:` are not created; create them via the SDK (`CreateSecret`, e.g. in a bootstrap step) for now. Wiring the provisioner is a follow-up.
20
21
 
21
22
  ## [0.10.0] - 2026-07-13
22
23
 
package/README.md CHANGED
@@ -19,16 +19,112 @@ flowchart LR
19
19
 
20
20
  ## Features
21
21
 
22
- - **⚡ Self engine (the LSS differentiator)**: DynamoDB, SQS, S3, EventBridge, OpenSearch Serverless, SNS and the Lambda control plane emulated **in-process** by the orchestrator — no Docker, no LocalStack, no auth token. Boots in milliseconds, stores data in local files, delivers events straight into your handlers. See [Self engine](#self-engine--no-docker-no-localstack-no-auth-token) below.
23
- - **Centralized provisioning**: Parses CloudFormation templates from `sls package` and provisions resources automatically into the self engine or a single shared LocalStack, your choice per instance
24
- - **Event source mappings**: Automatically connects SQS queues, streams, S3 notifications and EventBridge rules to Lambda handlers
25
- - **Lambda runtime & API emulation**: LSS answers on the same API (30xx) and Lambda invoke (130xx) ports that serverless-offline used
26
- - **Web UI**: Vue 3 dashboard to monitor services, resources, and event mappings — [brandable with your company's colors and logo](docs/CONFIGURATION.md#configuration-properties)
27
- - **Hot reload**: Watch for code changes and auto-rebuild/reprovision
28
- - **DynamoDB seeds**: fixtures auto-applied on table creation, re-applied via `lss seed` or the dashboard
29
- - **CLI + programmatic client**: manage the orchestrator from the shell (`npx lss …`) or from code (`LssClient`)
30
-
31
- See [docs/FEATURES.md](docs/FEATURES.md) for the complete feature inventory and how each capability is tested.
22
+ > **⚠️ Keep this inventory alive.** Every new capability MUST be added here **and** to the
23
+ > canonical inventory in [docs/FEATURES.md](docs/FEATURES.md)plus
24
+ > [docs/SELF_ENGINE.md](docs/SELF_ENGINE.md) when it touches the self engine. Treat a feature that
25
+ > isn't listed as a feature that doesn't exist: keeping these three documents in sync is part of
26
+ > shipping the change, not an afterthought.
27
+
28
+ LSS features come in two layers:
29
+
30
+ - **Platform** — the orchestrator, CLI, dashboard, plugin, programmatic client, Lambda/API runtime
31
+ and seeds. **Engine-agnostic:** they behave the same whichever backend you choose.
32
+ - **AWS engine** — the backend that actually serves the AWS wire protocols. You pick **one per
33
+ instance**: LocalStack Free, LocalStack Ultimate (Pro), or the in-process self engine.
34
+
35
+ ### 🧩 Platform (engine-agnostic)
36
+
37
+ - **CLI (`npx lss …`)**
38
+ - `start` — runs the orchestrator detached (PID + log files), flags `--self-engine`, `--external`, `--pro`, `--localstack-token`, `--enable-dynamo-proxy`, `--config`
39
+ - `status` · `logs` · `stop` (also tears down the managed LocalStack)
40
+ - `seed [table]` / `seed:clear [table] -y` — apply / wipe DynamoDB fixtures (hard local-endpoint guard on clear)
41
+ - `help` — every command, flag and a config template
42
+ - **Orchestration & provisioning**
43
+ - Service registration API (`POST /api/services/register`) — the plugin reports only *where* the service lives
44
+ - CloudFormation parsing from `sls package` → auto-provisions tables, queues, topics, buckets, EventBridge buses/rules and OpenSearch collections
45
+ - `autoPackage` — runs `sls package` on demand when the template is missing
46
+ - Automatic event source mappings: SQS / DynamoDB streams / S3 notifications / EventBridge rules → Lambda
47
+ - Per-instance isolation — `stateDir` + port-scoped PID/log paths let many LSS instances coexist (one per project)
48
+ - Config: `lss.config.json` / `.lssrc` + env overrides (`LSS_*`); public-safe `GET /api/config` snapshot (never leaks the auth token)
49
+ - **Lambda runtime & API Gateway emulation** (serverless-offline replacement — same `30xx`/`130xx` ports)
50
+ - Function + route registry: REST (`http`, payload v1), HTTP API (`httpApi`, payload v2) and authorizers — persisted and rehydrated on restart
51
+ - Per-service worker processes: lazy/warm handler loading, function env/timeout/context, per-invocation log capture, crash restart
52
+ - Execution modes: `artifact` (extracted zip) · `source` (direct require/import; TS via native type-stripping → esbuild/tsx/ts-node) · `auto`
53
+ - Lambda Invoke API on `130xx` (`X-Amz-Invocation-Type` RequestResponse/Event/DryRun, `X-Amz-Function-Error`)
54
+ - API Gateway proxy on `30xx`: route precedence (literal > `{param}` > `{proxy+}` > `$default`, method > ANY), payload v1/v2, CORS preflight, `port-conflict` status
55
+ - Lambda authorizers: REST `token`/`request`, HTTP API `request` (simple responses), identity-source extraction, TTL cache + cache-clear, cross-service resolution by ARN
56
+ - Hot reload: source changes restart the worker; `serverless.yml` changes re-package + re-register
57
+ - **Explorers & testing primitives** (HTTP API + dashboard)
58
+ - **Queues** (`/api/queues`): list + metrics (available/inFlight/processed/delayed), send/receive/delete/purge (FIFO group/dedup), `reset-processed`, `await-idle` (block until drained), `hold`/`captured`/`release` (capture-and-replay)
59
+ - **DynamoDB** (`/api/dynamo`): list/describe (keys, GSI/LSI, stream, TTL), scan/query with filters, item CRUD, get/set TTL
60
+ - **S3** (`/api/buckets`): list buckets (size/versioning/notifications), list/stream/upload (base64 or utf8)/delete objects
61
+ - **OpenSearch** (`/api/opensearch`): list collections, per-collection indices, run search queries
62
+ - **Secrets** (`/api/secrets`): list/describe secrets, reveal current value (separate endpoint so lists never carry secret material)
63
+ - **Seeds** (`/api/seeds`): auto-seed on table creation + on-demand run/clear, seed-file ↔ live-table mismatch diagnostic
64
+ - **Resources** (`/api/resources`, `…/owners`): provisioned resources mapped to owning services
65
+ - **Health** (`/api/health`): orchestrator + active engine + dynamo-proxy status
66
+ - **Dashboard (Vue 3 SPA)** — nine tabs: **Overview**, **Services** (status/start/stop/logs + per-service resource breakdown incl. EventBridge buses & rules and OpenSearch collections), **Lambdas** (registry + invoke + logs), **APIs**, **Queues**, **S3**, **DynamoDB**, **OpenSearch**, **Secrets** — plus a region selector and theme toggle
67
+ - **Branding**: navbar title/subtitle, logo, favicon, default theme and any TreeUI color token per theme, via the `branding` config key
68
+ - **serverless-lss plugin** — auto-registers each service on `sls package`/`offline`; orchestrator URL precedence (`ORCHESTRATOR_URL` > `LSS_DASHBOARD_PORT` > `custom.orchestrator` > 3100)
69
+ - **Programmatic client (`LssClient`)** — the CLI/dashboard surface from code: HTTP namespaces `seeds`, `queues`, `dynamo`, `buckets`, `resources`, `services`, `lambdas`, `apis`, `config`, `health` + `lifecycle` (`start`/`stop`/`status`/`logs`/`waitUntilReady`, shells out to the CLI)
70
+ - **DynamoDB dev proxy** — optional reverse proxy on `:8000` (`enableDynamoProxy`) forwarding to the active engine, for tooling that expects DynamoDB on the standard port
71
+ - **DynamoDB seeds** — `seeds/{tableName}.json` fixtures auto-applied on table creation, re-applied via `lss seed` or the dashboard
72
+
73
+ ### 🆓 Engine: LocalStack Free (community image, Docker)
74
+
75
+ LSS spins up and manages its own community LocalStack container (`lss-localstack-<port>`) with
76
+ `dynamodb, sqs, sns, s3, lambda, events`, a persistence volume and the local Lambda executor. Events
77
+ reach your handlers through a generated proxy Lambda inside the container that calls the LSS invoke
78
+ listener. This is the default engine; the [localstack-free example](examples/localstack-free/) runs
79
+ community 4.0 with no token.
80
+
81
+ - **Provisioned & wired**: DynamoDB tables (keys, GSI/LSI, streams, TTL), SQS queues (incl. FIFO), SNS topics, S3 buckets (versioning + `s3:ObjectCreated:*` notifications), EventBridge buses & rules (pattern or `rate()`/cron schedules), Lambda event source mappings
82
+ - **Not available on community**: OpenSearch Serverless (`aoss`) — provisioning fails with an explicit error pointing you at Pro or the self engine
83
+ - Community images `>= 2026.5` require `LOCALSTACK_AUTH_TOKEN`; `mode: external` / `--external` points at a LocalStack you already run
84
+
85
+ ### 💎 Engine: LocalStack Ultimate (Pro image, auth token)
86
+
87
+ `npx lss start --pro` (optionally `--localstack-token ls-xxx`) runs the LocalStack **Pro** image — same
88
+ provisioning and wiring as Free, plus the Pro-only services (OpenSearch Serverless and more). The
89
+ [localstack-ultimate example](examples/localstack-ultimate/) keeps the serverless-offline path in
90
+ charge of the ports and exercises the full resource menu (custom bus + pattern rule with an audit
91
+ trail, `rate()` schedule, SQS DLQ redrive with `ReportBatchItemFailures`, DynamoDB GSI + streams →
92
+ SNS, S3 notifications, TTL from the UI).
93
+
94
+ - Requires `LOCALSTACK_AUTH_TOKEN` (Ultimate plan)
95
+ - `localstackEdition` / `localstackVersion` / `localstackImage` select the exact image
96
+
97
+ ### ⚡ Engine: Self (in-process AWS emulator — no Docker, no token) — *the LSS differentiator*
98
+
99
+ The orchestrator serves the AWS wire protocols itself on one port (default `14566`); events are
100
+ delivered **in-process** straight to the LSS Lambda runtime — no container, no proxy Lambdas, no
101
+ polling. Data persists as JSONL snapshot + WAL / content-addressed blobs under `~/.lss/engine`,
102
+ hydrated on first touch and dehydrated when idle. Anything unimplemented answers with an explicit
103
+ AWS-shaped error or is forwarded to `selfEngine.fallbackEndpoint`. See the [Self engine
104
+ section](#self-engine--no-docker-no-localstack-no-auth-token) below for boot-time numbers and the
105
+ migration story, and [docs/SELF_ENGINE.md](docs/SELF_ENGINE.md) for the full coverage matrix.
106
+
107
+ - **DynamoDB**
108
+ - Full expression language: KeyCondition, Condition, Filter, Update, Projection — decimal-exact `N` arithmetic
109
+ - GSI/LSI with projection + sparse semantics; Limit-before-filter parity; LEK paging
110
+ - Item ops: Put/Get/Delete/UpdateItem, Query, Scan, BatchGet/BatchWrite, TransactWrite/TransactGet (all-or-nothing, `CancellationReasons`, `ClientRequestToken` idempotency)
111
+ - **Streams** delivered in-process (TRIM_HORIZON/LATEST, retry-then-advance, OnFailure SQS destination)
112
+ - Lazy **TTL** expiry; AWS error names the provisioner relies on
113
+ - Works unchanged with platform **seeds**, the DynamoDB explorer and the dev proxy
114
+ - **SQS** — CreateQueue (idempotent), send/receive(+batch)/delete/purge, ChangeMessageVisibility; FIFO groups/dedup, event-driven long poll, visibility redelivery, live counters, MD5 digests, `x-amzn-query-error` compat header (`RedrivePolicy` round-trips but DLQ redrive is not enforced)
115
+ - **S3** — buckets (create/head/delete/list, location, versioning flag), ListObjectsV2 (prefix/delimiter/pagination/encoding), PutObject (aws-chunked), **presigned POST browser uploads** (`multipart/form-data`, `${filename}`, `success_action_status`/`redirect`, `x-amz-meta-*`), GetObject (Range), HeadObject, DeleteObject(s), CopyObject, notification config — bodies streamed to disk, never held in heap
116
+ - **EventBridge** — buses/rules/targets, PutEvents per-entry results, pattern matcher (exact, array-OR, `prefix`, `exists`, nested), schedules (`rate()` + 6-field cron) from one timer wheel
117
+ - **OpenSearch Serverless** — `aoss` control plane (Create/BatchGet/List/DeleteCollection, deterministic ids, `collectionEndpoint`) + REST data plane under `/_aoss/<collection>`: index & document CRUD with versioning, `_bulk` NDJSON, `_search`/`_count` (match/term/terms/range/prefix/wildcard/exists/ids/bool + sort, `_source` filtering, `?q=`), `terms`+metric aggregations, `_mapping`, `_refresh`, `_cat/indices`
118
+ - **Secrets Manager** — Create/Get/Put/Update/Describe/Delete/Restore/ListSecrets, Tag/Untag, GetRandomPassword; real `AWSCURRENT`/`AWSPREVIOUS` staging, `SecretString`/`SecretBinary`, `ClientRequestToken` idempotency, per-region scoping (values persisted, not encrypted; create via SDK — CFN provisioning pending)
119
+ - **SNS** (minimal) — CreateTopic, ListTopics, DeleteTopic, GetTopicAttributes, Publish (logged + counted, no fan-out)
120
+ - **STS** — GetCallerIdentity
121
+ - **Lambda control plane** — proxy absorption as metadata (`INVOKE_URL` kept as HTTP fallback), event source mapping lifecycle (`Enabled` toggle = QueueInspector hold/release), Invoke passthrough
122
+ - **In-process event delivery** — SQS→Lambda (batch size/window, visibility semantics), DynamoDB streams, S3 notifications (globs + prefix/suffix), EventBridge targets (`Input`/`InputPath`), schedules — all via `LambdaRuntimeManager.invoke()`, no proxies, no polling
123
+ - **Wire front door & storage** — single-port routing (SigV4-scope / X-Amz-Target / path), per-protocol error shapes, `/_localstack/health` alias, `fallbackEndpoint` reverse proxy; JSONL snapshot + WAL (torn-tail-safe, compaction), atomic JSON catalogs, content-addressed S3 blobs, hydrate-on-touch + idle dehydrate + `memoryBudgetMb` LRU
124
+
125
+ For how each capability is tested (unit vs integration) see [docs/FEATURES.md](docs/FEATURES.md); the
126
+ self-engine coverage matrix and known divergences from AWS live in
127
+ [docs/SELF_ENGINE.md](docs/SELF_ENGINE.md).
32
128
 
33
129
  ## Self engine — no Docker, no LocalStack, no auth token
34
130
 
@@ -68,7 +164,7 @@ What you get:
68
164
  flowchart LR
69
165
  APP[Your services<br/>AWS SDK → :14566] --> ENG
70
166
  subgraph ORCH["One orchestrator process — no Docker"]
71
- ENG[Self engine<br/>DynamoDB · SQS · S3 · EventBridge<br/>OpenSearch · SNS · STS]
167
+ ENG[Self engine<br/>DynamoDB · SQS · S3 · EventBridge<br/>OpenSearch · Secrets Manager · SNS · STS]
72
168
  ENG -->|in-process events| RT[LSS Lambda runtime<br/>your handlers, ports 30xx/130xx]
73
169
  ENG --- FS[(local files<br/>~/.lss/engine)]
74
170
  end
@@ -9,6 +9,7 @@ import { bucketsRouter } from './routes/buckets.js';
9
9
  import { seedsRouter } from './routes/seeds.js';
10
10
  import { dynamoRouter } from './routes/dynamo.js';
11
11
  import { opensearchRouter } from './routes/opensearch.js';
12
+ import { secretsRouter } from './routes/secrets.js';
12
13
  import { configRouter } from './routes/config.js';
13
14
  import { lambdasRouter } from './routes/lambdas.js';
14
15
  import { apisRouter } from './routes/apis.js';
@@ -38,6 +39,7 @@ app.use('/api/buckets', bucketsRouter);
38
39
  app.use('/api/seeds', seedsRouter);
39
40
  app.use('/api/dynamo', dynamoRouter);
40
41
  app.use('/api/opensearch', opensearchRouter);
42
+ app.use('/api/secrets', secretsRouter);
41
43
  app.use('/api/config', configRouter);
42
44
  app.use('/api/lambdas', lambdasRouter);
43
45
  app.use('/api/apis', apisRouter);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export { router as secretsRouter };
3
+ //# sourceMappingURL=secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../../src/server/routes/secrets.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA+DxB,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,CAAC"}
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../../src/server/routes/secrets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ export interface SecretSummary {
2
+ name: string;
3
+ arn?: string;
4
+ description?: string;
5
+ lastChangedDate?: string;
6
+ lastAccessedDate?: string;
7
+ createdDate?: string;
8
+ deletedDate?: string;
9
+ tags: Array<{
10
+ key: string;
11
+ value: string;
12
+ }>;
13
+ versionCount: number;
14
+ }
15
+ export interface SecretDetail extends SecretSummary {
16
+ versionStages: Record<string, string[]>;
17
+ kmsKeyId?: string;
18
+ }
19
+ export interface SecretValue {
20
+ name: string;
21
+ versionId?: string;
22
+ versionStages: string[];
23
+ secretString?: string;
24
+ secretBinary?: string;
25
+ createdDate?: string;
26
+ }
27
+ export declare class SecretsExplorer {
28
+ private static instance;
29
+ private clients;
30
+ private defaultRegion;
31
+ private constructor();
32
+ static getInstance(): SecretsExplorer;
33
+ setDefaultRegion(region: string): void;
34
+ private clientFor;
35
+ listSecrets(region?: string): Promise<SecretSummary[]>;
36
+ describeSecret(secretId: string, region?: string): Promise<SecretDetail | null>;
37
+ getSecretValue(secretId: string, region?: string): Promise<SecretValue | null>;
38
+ }
39
+ //# sourceMappingURL=secrets-explorer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets-explorer.d.ts","sourceRoot":"","sources":["../../../src/server/services/secrets-explorer.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5C,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAa,SAAQ,aAAa;IAEjD,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;IAExB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkB;IACzC,OAAO,CAAC,OAAO,CAA2C;IAC1D,OAAO,CAAC,aAAa,CAAe;IAEpC,OAAO;IAEP,MAAM,CAAC,WAAW,IAAI,eAAe;IAKrC,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAItC,OAAO,CAAC,SAAS;IAWX,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAYtD,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAwB/E,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;CAgBrF"}
@@ -0,0 +1,105 @@
1
+ // Read-only Secrets Manager explorer for the dashboard: lists secrets, reads
2
+ // one secret's metadata (version stages, tags) and — on explicit request —
3
+ // reveals the current value. Talks the AWS wire against the active engine
4
+ // endpoint, so it works identically on the self engine and LocalStack. Mirrors
5
+ // the DynamoExplorer/S3Explorer pattern (per-region memoized client, region
6
+ // from the request, AWS errors mapped to plain messages).
7
+ import { SecretsManagerClient, ListSecretsCommand, DescribeSecretCommand, GetSecretValueCommand, } from '@aws-sdk/client-secrets-manager';
8
+ import { LocalStackManager } from './localstack-manager.js';
9
+ export class SecretsExplorer {
10
+ static instance;
11
+ clients = new Map();
12
+ defaultRegion = 'us-east-1';
13
+ constructor() { }
14
+ static getInstance() {
15
+ if (!SecretsExplorer.instance)
16
+ SecretsExplorer.instance = new SecretsExplorer();
17
+ return SecretsExplorer.instance;
18
+ }
19
+ setDefaultRegion(region) {
20
+ if (region)
21
+ this.defaultRegion = region;
22
+ }
23
+ clientFor(region) {
24
+ const r = region || this.defaultRegion;
25
+ let client = this.clients.get(r);
26
+ if (!client) {
27
+ const baseConfig = LocalStackManager.getInstance().getConfig();
28
+ client = new SecretsManagerClient({ ...baseConfig, region: r });
29
+ this.clients.set(r, client);
30
+ }
31
+ return client;
32
+ }
33
+ async listSecrets(region) {
34
+ const client = this.clientFor(region);
35
+ const summaries = [];
36
+ let nextToken;
37
+ do {
38
+ const page = await client.send(new ListSecretsCommand({ NextToken: nextToken, MaxResults: 100 }));
39
+ for (const entry of page.SecretList ?? [])
40
+ summaries.push(toSummary(entry));
41
+ nextToken = page.NextToken;
42
+ } while (nextToken);
43
+ return summaries.sort((a, b) => a.name.localeCompare(b.name));
44
+ }
45
+ async describeSecret(secretId, region) {
46
+ try {
47
+ const res = await this.clientFor(region).send(new DescribeSecretCommand({ SecretId: secretId }));
48
+ return {
49
+ name: res.Name ?? secretId,
50
+ arn: res.ARN,
51
+ description: res.Description,
52
+ lastChangedDate: res.LastChangedDate?.toISOString(),
53
+ lastAccessedDate: res.LastAccessedDate?.toISOString(),
54
+ createdDate: res.CreatedDate?.toISOString(),
55
+ deletedDate: res.DeletedDate?.toISOString(),
56
+ tags: (res.Tags ?? []).map(tag => ({ key: tag.Key ?? '', value: tag.Value ?? '' })),
57
+ versionCount: Object.keys(res.VersionIdsToStages ?? {}).length,
58
+ versionStages: res.VersionIdsToStages ?? {},
59
+ kmsKeyId: res.KmsKeyId,
60
+ };
61
+ }
62
+ catch (error) {
63
+ if (isNotFound(error))
64
+ return null;
65
+ throw error;
66
+ }
67
+ }
68
+ // Reveals the current secret value — an explicit, separate call so a plain
69
+ // list never ships secret material to the browser.
70
+ async getSecretValue(secretId, region) {
71
+ try {
72
+ const res = await this.clientFor(region).send(new GetSecretValueCommand({ SecretId: secretId }));
73
+ return {
74
+ name: res.Name ?? secretId,
75
+ versionId: res.VersionId,
76
+ versionStages: res.VersionStages ?? [],
77
+ secretString: res.SecretString,
78
+ secretBinary: res.SecretBinary ? Buffer.from(res.SecretBinary).toString('base64') : undefined,
79
+ createdDate: res.CreatedDate?.toISOString(),
80
+ };
81
+ }
82
+ catch (error) {
83
+ if (isNotFound(error))
84
+ return null;
85
+ throw error;
86
+ }
87
+ }
88
+ }
89
+ function toSummary(entry) {
90
+ return {
91
+ name: entry.Name ?? '',
92
+ arn: entry.ARN,
93
+ description: entry.Description,
94
+ lastChangedDate: entry.LastChangedDate?.toISOString(),
95
+ lastAccessedDate: entry.LastAccessedDate?.toISOString(),
96
+ createdDate: entry.CreatedDate?.toISOString(),
97
+ deletedDate: entry.DeletedDate?.toISOString(),
98
+ tags: (entry.Tags ?? []).map(tag => ({ key: tag.Key ?? '', value: tag.Value ?? '' })),
99
+ versionCount: Object.keys(entry.SecretVersionsToStages ?? {}).length,
100
+ };
101
+ }
102
+ function isNotFound(error) {
103
+ return error instanceof Error && error.name === 'ResourceNotFoundException';
104
+ }
105
+ //# sourceMappingURL=secrets-explorer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets-explorer.js","sourceRoot":"","sources":["../../../src/server/services/secrets-explorer.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- import{k as V,l as E,o as G,m as i,e as c,U as a,t as _,Z as e,j as s,w as X,x as N,G as Y,i as u,T as r,f,g as p,s as Z,z as x,F as T,n as H,q as J,A as S,y as I,u as h,R as P,d as y,p as z,v as K,r as b,b as O,a as R,c as Q}from"./index-BP9zQ9L-.js";const W={key:1,style:{display:"flex","justify-content":"center",padding:"2rem"}},ee={style:{"text-decoration":"underline","text-decoration-style":"dotted","text-underline-offset":"3px"}},te={class:"mono"},ae={key:1,class:"muted"},ne={class:"mono",style:{"font-size":"0.8rem"}},oe={class:"mono",style:{"font-size":"0.8rem"}},le={class:"mono",style:{"font-size":"0.75rem"}},se={key:0,class:"mono",style:{"font-size":"0.75rem"}},re={key:1,class:"muted"},ie=V({__name:"ApisView",setup(F){const k=Q(),d=b([]),v=b(!0),g=b(null),m=b({});let $=null;const j=[{key:"method",label:"Method"},{key:"path",label:"Path"},{key:"functionName",label:"→ Function"},{key:"eventType",label:"Type"},{key:"authorizerName",label:"Auth"},{key:"actions",label:"",align:"right"}],B=[{key:"name",label:"Name"},{key:"type",label:"Type"},{key:"payloadVersion",label:"Payload"},{key:"resultTtlInSeconds",label:"TTL",align:"right"},{key:"identitySource",label:"Identity source"},{key:"target",label:"Function / ARN"}],w=O(()=>({services:d.value.length,routes:d.value.reduce((l,n)=>l+n.routes.length,0),online:d.value.filter(l=>l.status==="online").length}));function L(l){return l.routes.map(n=>({...n}))}function U(l){return l.authorizers.map(n=>({...n,identitySource:n.identitySource.join(", "),target:n.functionName||n.arn||""}))}async function A(){try{d.value=await R.listApis(),g.value=null}catch(l){g.value=l.message||"Failed to load APIs"}finally{v.value=!1}}async function D(l){if(!m.value[l]){m.value={...m.value,[l]:!0};try{const n=await R.clearAuthorizerCache({service:l});k.add({title:"Authorizer cache cleared",description:`${n.removed} cached result${n.removed===1?"":"s"} removed`,variant:"success"})}catch(n){k.add({title:"Failed to clear authorizer cache",description:n.message,variant:"danger"})}finally{m.value={...m.value,[l]:!1}}}}function M(l,n){var t;const o=`curl -X ${n.method} http://localhost:${l.apiPort}${n.path}`;(t=navigator.clipboard)==null||t.writeText(o).then(()=>{k.add({title:"curl command copied",description:o,variant:"success"})})}function C(l){switch(l){case"online":return"success";case"port-conflict":return"warning";default:return"neutral"}}function q(l){return l==="ANY"?"info":"neutral"}return E(()=>{A(),$=window.setInterval(A,1e4)}),G(()=>{$&&window.clearInterval($)}),(l,n)=>(i(),c(a(_),{direction:"vertical",gap:"1.25rem"},{default:e(()=>[s(a(X),{columns:3,gap:"1rem"},{default:e(()=>[s(a(N),{label:"Services with APIs",value:w.value.services,tone:"info",loading:v.value},null,8,["value","loading"]),s(a(N),{label:"Routes",value:w.value.routes,tone:"info",loading:v.value},null,8,["value","loading"]),s(a(N),{label:"Listeners online",value:w.value.online,tone:"success",loading:v.value},null,8,["value","loading"])]),_:1}),g.value?(i(),c(a(Y),{key:0,variant:"danger",dismissible:"",onDismiss:n[0]||(n[0]=o=>g.value=null)},{default:e(()=>[u(r(g.value),1)]),_:1})):f("",!0),v.value&&!d.value.length?(i(),p("div",W,[s(a(Z),{label:"Loading APIs..."})])):d.value.length?f("",!0):(i(),c(a(x),{key:2,title:"No APIs registered",description:"Register a microservice that defines http or httpApi events to see its routes here."})),(i(!0),p(T,null,H(d.value,o=>(i(),c(a(J),{key:o.service,variant:"outline"},{header:e(()=>[s(a(_),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between",wrap:""},{default:e(()=>[s(a(_),{direction:"horizontal",gap:"0.5rem",align:"center",wrap:""},{default:e(()=>[s(a(P),{to:`/services/${encodeURIComponent(o.service)}`,style:{color:"inherit","text-decoration":"none"}},{default:e(()=>[y("strong",ee,r(o.service),1)]),_:2},1032,["to"]),o.apiPort?(i(),c(a(z),{key:0,tone:"info",variant:"soft"},{default:e(()=>[u(":"+r(o.apiPort),1)]),_:2},1024)):f("",!0),s(a(z),{tone:C(o.status),variant:"soft"},{default:e(()=>[u(r(o.status),1)]),_:2},1032,["tone"]),o.invokePort?(i(),c(a(z),{key:1,tone:C(o.invokeStatus),variant:"soft"},{default:e(()=>[u(" invoke :"+r(o.invokePort),1)]),_:2},1032,["tone"])):f("",!0),o.stage?(i(),c(a(h),{key:2,size:"sm",variant:"soft"},{default:e(()=>[u("stage: "+r(o.stage),1)]),_:2},1024)):f("",!0)]),_:2},1024),s(a(I),{size:"sm",variant:"ghost",loading:m.value[o.service],onClick:t=>D(o.service)},{default:e(()=>[...n[1]||(n[1]=[u(" Clear authorizer cache ",-1)])]),_:1},8,["loading","onClick"])]),_:2},1024)]),default:e(()=>[s(a(_),{direction:"vertical",gap:"0.75rem"},{default:e(()=>[o.routes.length?(i(),c(a(S),{key:0,columns:j,rows:L(o)},{"cell-method":e(({row:t})=>[s(a(z),{tone:q(String(t.method)),variant:"soft"},{default:e(()=>[u(r(t.method),1)]),_:2},1032,["tone"])]),"cell-path":e(({row:t})=>[y("span",te,r(t.path),1)]),"cell-functionName":e(({row:t})=>[s(a(P),{to:`/lambdas/${encodeURIComponent(String(t.functionName))}`,style:{"text-decoration":"none"}},{default:e(()=>[s(a(h),{size:"sm",variant:"soft",clickable:""},{default:e(()=>[u(r(t.functionName),1)]),_:2},1024)]),_:2},1032,["to"])]),"cell-eventType":e(({row:t})=>[s(a(h),{size:"sm",variant:"soft"},{default:e(()=>[u(r(t.payloadVersion==="2.0"?"v2":"v1"),1)]),_:2},1024)]),"cell-authorizerName":e(({row:t})=>[t.authorizerName?(i(),c(a(h),{key:0,size:"sm",variant:"soft"},{default:e(()=>[u(r(t.authorizerName),1)]),_:2},1024)):(i(),p("span",ae,"—"))]),"cell-actions":e(({row:t})=>[s(a(_),{direction:"horizontal",gap:"0.375rem",justify:"flex-end"},{default:e(()=>[s(a(I),{size:"sm",variant:"ghost",onClick:ue=>M(o,t)},{default:e(()=>[...n[2]||(n[2]=[u(" Copy curl ",-1)])]),_:1},8,["onClick"])]),_:2},1024)]),_:2},1032,["rows"])):(i(),c(a(x),{key:1,title:"No routes",description:"This service exposes no http or httpApi routes."})),o.authorizers.length?(i(),p(T,{key:2},[s(a(K)),n[3]||(n[3]=y("strong",{style:{"font-size":"0.85rem"}},"Authorizers",-1)),s(a(S),{columns:B,rows:U(o)},{"cell-name":e(({row:t})=>[y("span",ne,r(t.name),1)]),"cell-type":e(({row:t})=>[s(a(h),{size:"sm",variant:"soft"},{default:e(()=>[u(r(t.type),1)]),_:2},1024)]),"cell-payloadVersion":e(({row:t})=>[s(a(h),{size:"sm",variant:"soft"},{default:e(()=>[u(r(t.payloadVersion==="2.0"?"v2":"v1"),1)]),_:2},1024)]),"cell-resultTtlInSeconds":e(({row:t})=>[y("span",oe,r(t.resultTtlInSeconds)+"s",1)]),"cell-identitySource":e(({row:t})=>[y("span",le,r(t.identitySource||"—"),1)]),"cell-target":e(({row:t})=>[t.target?(i(),p("span",se,r(t.target),1)):(i(),p("span",re,"—"))]),_:1},8,["rows"])],64)):f("",!0)]),_:2},1024)]),_:2},1024))),128))]),_:1}))}}),de=V({__name:"ApisPage",setup(F){return(k,d)=>(i(),c(ie))}});export{de as default};
1
+ import{k as V,l as E,o as G,m as i,e as c,U as a,t as _,Z as e,j as s,w as X,x as N,G as Y,i as u,T as r,f,g as p,s as Z,z as x,F as T,n as H,q as J,A as S,y as I,u as h,R as P,d as y,p as z,v as K,r as b,b as O,a as R,c as Q}from"./index-DGkmrq2b.js";const W={key:1,style:{display:"flex","justify-content":"center",padding:"2rem"}},ee={style:{"text-decoration":"underline","text-decoration-style":"dotted","text-underline-offset":"3px"}},te={class:"mono"},ae={key:1,class:"muted"},ne={class:"mono",style:{"font-size":"0.8rem"}},oe={class:"mono",style:{"font-size":"0.8rem"}},le={class:"mono",style:{"font-size":"0.75rem"}},se={key:0,class:"mono",style:{"font-size":"0.75rem"}},re={key:1,class:"muted"},ie=V({__name:"ApisView",setup(F){const k=Q(),d=b([]),v=b(!0),g=b(null),m=b({});let $=null;const j=[{key:"method",label:"Method"},{key:"path",label:"Path"},{key:"functionName",label:"→ Function"},{key:"eventType",label:"Type"},{key:"authorizerName",label:"Auth"},{key:"actions",label:"",align:"right"}],B=[{key:"name",label:"Name"},{key:"type",label:"Type"},{key:"payloadVersion",label:"Payload"},{key:"resultTtlInSeconds",label:"TTL",align:"right"},{key:"identitySource",label:"Identity source"},{key:"target",label:"Function / ARN"}],w=O(()=>({services:d.value.length,routes:d.value.reduce((l,n)=>l+n.routes.length,0),online:d.value.filter(l=>l.status==="online").length}));function L(l){return l.routes.map(n=>({...n}))}function U(l){return l.authorizers.map(n=>({...n,identitySource:n.identitySource.join(", "),target:n.functionName||n.arn||""}))}async function A(){try{d.value=await R.listApis(),g.value=null}catch(l){g.value=l.message||"Failed to load APIs"}finally{v.value=!1}}async function D(l){if(!m.value[l]){m.value={...m.value,[l]:!0};try{const n=await R.clearAuthorizerCache({service:l});k.add({title:"Authorizer cache cleared",description:`${n.removed} cached result${n.removed===1?"":"s"} removed`,variant:"success"})}catch(n){k.add({title:"Failed to clear authorizer cache",description:n.message,variant:"danger"})}finally{m.value={...m.value,[l]:!1}}}}function M(l,n){var t;const o=`curl -X ${n.method} http://localhost:${l.apiPort}${n.path}`;(t=navigator.clipboard)==null||t.writeText(o).then(()=>{k.add({title:"curl command copied",description:o,variant:"success"})})}function C(l){switch(l){case"online":return"success";case"port-conflict":return"warning";default:return"neutral"}}function q(l){return l==="ANY"?"info":"neutral"}return E(()=>{A(),$=window.setInterval(A,1e4)}),G(()=>{$&&window.clearInterval($)}),(l,n)=>(i(),c(a(_),{direction:"vertical",gap:"1.25rem"},{default:e(()=>[s(a(X),{columns:3,gap:"1rem"},{default:e(()=>[s(a(N),{label:"Services with APIs",value:w.value.services,tone:"info",loading:v.value},null,8,["value","loading"]),s(a(N),{label:"Routes",value:w.value.routes,tone:"info",loading:v.value},null,8,["value","loading"]),s(a(N),{label:"Listeners online",value:w.value.online,tone:"success",loading:v.value},null,8,["value","loading"])]),_:1}),g.value?(i(),c(a(Y),{key:0,variant:"danger",dismissible:"",onDismiss:n[0]||(n[0]=o=>g.value=null)},{default:e(()=>[u(r(g.value),1)]),_:1})):f("",!0),v.value&&!d.value.length?(i(),p("div",W,[s(a(Z),{label:"Loading APIs..."})])):d.value.length?f("",!0):(i(),c(a(x),{key:2,title:"No APIs registered",description:"Register a microservice that defines http or httpApi events to see its routes here."})),(i(!0),p(T,null,H(d.value,o=>(i(),c(a(J),{key:o.service,variant:"outline"},{header:e(()=>[s(a(_),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between",wrap:""},{default:e(()=>[s(a(_),{direction:"horizontal",gap:"0.5rem",align:"center",wrap:""},{default:e(()=>[s(a(P),{to:`/services/${encodeURIComponent(o.service)}`,style:{color:"inherit","text-decoration":"none"}},{default:e(()=>[y("strong",ee,r(o.service),1)]),_:2},1032,["to"]),o.apiPort?(i(),c(a(z),{key:0,tone:"info",variant:"soft"},{default:e(()=>[u(":"+r(o.apiPort),1)]),_:2},1024)):f("",!0),s(a(z),{tone:C(o.status),variant:"soft"},{default:e(()=>[u(r(o.status),1)]),_:2},1032,["tone"]),o.invokePort?(i(),c(a(z),{key:1,tone:C(o.invokeStatus),variant:"soft"},{default:e(()=>[u(" invoke :"+r(o.invokePort),1)]),_:2},1032,["tone"])):f("",!0),o.stage?(i(),c(a(h),{key:2,size:"sm",variant:"soft"},{default:e(()=>[u("stage: "+r(o.stage),1)]),_:2},1024)):f("",!0)]),_:2},1024),s(a(I),{size:"sm",variant:"ghost",loading:m.value[o.service],onClick:t=>D(o.service)},{default:e(()=>[...n[1]||(n[1]=[u(" Clear authorizer cache ",-1)])]),_:1},8,["loading","onClick"])]),_:2},1024)]),default:e(()=>[s(a(_),{direction:"vertical",gap:"0.75rem"},{default:e(()=>[o.routes.length?(i(),c(a(S),{key:0,columns:j,rows:L(o)},{"cell-method":e(({row:t})=>[s(a(z),{tone:q(String(t.method)),variant:"soft"},{default:e(()=>[u(r(t.method),1)]),_:2},1032,["tone"])]),"cell-path":e(({row:t})=>[y("span",te,r(t.path),1)]),"cell-functionName":e(({row:t})=>[s(a(P),{to:`/lambdas/${encodeURIComponent(String(t.functionName))}`,style:{"text-decoration":"none"}},{default:e(()=>[s(a(h),{size:"sm",variant:"soft",clickable:""},{default:e(()=>[u(r(t.functionName),1)]),_:2},1024)]),_:2},1032,["to"])]),"cell-eventType":e(({row:t})=>[s(a(h),{size:"sm",variant:"soft"},{default:e(()=>[u(r(t.payloadVersion==="2.0"?"v2":"v1"),1)]),_:2},1024)]),"cell-authorizerName":e(({row:t})=>[t.authorizerName?(i(),c(a(h),{key:0,size:"sm",variant:"soft"},{default:e(()=>[u(r(t.authorizerName),1)]),_:2},1024)):(i(),p("span",ae,"—"))]),"cell-actions":e(({row:t})=>[s(a(_),{direction:"horizontal",gap:"0.375rem",justify:"flex-end"},{default:e(()=>[s(a(I),{size:"sm",variant:"ghost",onClick:ue=>M(o,t)},{default:e(()=>[...n[2]||(n[2]=[u(" Copy curl ",-1)])]),_:1},8,["onClick"])]),_:2},1024)]),_:2},1032,["rows"])):(i(),c(a(x),{key:1,title:"No routes",description:"This service exposes no http or httpApi routes."})),o.authorizers.length?(i(),p(T,{key:2},[s(a(K)),n[3]||(n[3]=y("strong",{style:{"font-size":"0.85rem"}},"Authorizers",-1)),s(a(S),{columns:B,rows:U(o)},{"cell-name":e(({row:t})=>[y("span",ne,r(t.name),1)]),"cell-type":e(({row:t})=>[s(a(h),{size:"sm",variant:"soft"},{default:e(()=>[u(r(t.type),1)]),_:2},1024)]),"cell-payloadVersion":e(({row:t})=>[s(a(h),{size:"sm",variant:"soft"},{default:e(()=>[u(r(t.payloadVersion==="2.0"?"v2":"v1"),1)]),_:2},1024)]),"cell-resultTtlInSeconds":e(({row:t})=>[y("span",oe,r(t.resultTtlInSeconds)+"s",1)]),"cell-identitySource":e(({row:t})=>[y("span",le,r(t.identitySource||"—"),1)]),"cell-target":e(({row:t})=>[t.target?(i(),p("span",se,r(t.target),1)):(i(),p("span",re,"—"))]),_:1},8,["rows"])],64)):f("",!0)]),_:2},1024)]),_:2},1024))),128))]),_:1}))}}),de=V({__name:"ApisPage",setup(F){return(k,d)=>(i(),c(ie))}});export{de as default};
@@ -1 +1 @@
1
- import{k as E,l as X,Y,e as k,U as t,t as c,Z as n,a as b,m as d,j as o,y as g,i as r,d as m,T as p,p as Z,f as M,G as I,g as U,s as F,x as $,w as J,E as S,_ as Q,X as ee,q as _,z as te,A as ae,$ as le,F as ne,c as oe,r as u,b as ie,W as re}from"./index-BP9zQ9L-.js";const ue={style:{"font-size":"1.1rem"}},se={key:1,style:{display:"flex","justify-content":"center",padding:"2rem"}},de={key:0,style:{display:"flex","justify-content":"center",padding:"2rem"}},ce=["href"],fe=["href"],ve=E({__name:"BucketDetail",props:{bucketName:{}},emits:["back"],setup(z,{emit:N}){const s=z,K=N,f=oe(),i=u(null),y=u([]),V=u(""),T=u(!0),B=u(!1),j=u(null),w=u(""),x=u(""),h=u("text/plain"),C=u(!1),L=[{key:"key",label:"Key"},{key:"size",label:"Size",align:"right"},{key:"lastModified",label:"Modified"},{key:"actions",label:"",align:"right"}],q=ie(()=>y.value.reduce((l,e)=>l+(e.size||0),0));function O(l){if(l==null)return"—";if(l===0)return"0 B";const e=["B","KB","MB","GB","TB"],a=Math.floor(Math.log(l)/Math.log(1024));return`${(l/Math.pow(1024,a)).toFixed(a===0?0:1)} ${e[a]}`}function A(l){return l?new Date(l).toLocaleString():"—"}async function D(){try{i.value=await b.getBucket(s.bucketName),j.value=null}catch(l){j.value=l.message||"Failed to load bucket",i.value=null}finally{T.value=!1}}async function v(){B.value=!0;try{const l=await b.listBucketObjects(s.bucketName,{prefix:V.value||void 0,maxKeys:200});y.value=l.objects}catch(l){f.add({title:"Failed to load objects",description:l.message,variant:"danger"})}finally{B.value=!1}}function G(l){return b.bucketObjectContentUrl(s.bucketName,l,!1)}function R(l){return b.bucketObjectContentUrl(s.bucketName,l,!0)}async function H(l){if(confirm(`Delete object "${l}"?`))try{await b.deleteBucketObject(s.bucketName,l),f.add({title:"Object deleted",variant:"info"}),await v()}catch(e){f.add({title:"Failed to delete object",description:e.message,variant:"danger"})}}async function P(){if(!w.value||!x.value){f.add({title:"Key and body are required",variant:"warning"});return}C.value=!0;try{await b.putBucketObject(s.bucketName,{key:w.value,body:x.value,contentType:h.value||void 0}),f.add({title:"Object uploaded",variant:"info"}),w.value="",x.value="",await v(),await D()}catch(l){f.add({title:"Failed to upload object",description:l.message,variant:"danger"})}finally{C.value=!1}}return X(()=>{D(),v()}),Y(()=>s.bucketName,()=>{D(),v()}),(l,e)=>(d(),k(t(c),{direction:"vertical",gap:"1rem"},{default:n(()=>[o(t(c),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between"},{default:n(()=>[o(t(c),{direction:"horizontal",gap:"0.5rem",align:"center"},{default:n(()=>{var a;return[o(t(g),{size:"sm",variant:"ghost",onClick:e[0]||(e[0]=W=>K("back"))},{default:n(()=>[...e[9]||(e[9]=[r("← Buckets",-1)])]),_:1}),m("strong",ue,p(z.bucketName),1),(a=i.value)!=null&&a.versioning?(d(),k(t(Z),{key:0,tone:"info",variant:"soft"},{default:n(()=>[...e[10]||(e[10]=[r("Versioning",-1)])]),_:1})):M("",!0)]}),_:1}),o(t(g),{size:"sm",variant:"ghost",loading:B.value,onClick:e[1]||(e[1]=a=>v())},{default:n(()=>[...e[11]||(e[11]=[r("Refresh",-1)])]),_:1},8,["loading"])]),_:1}),j.value?(d(),k(t(I),{key:0,variant:"danger",dismissible:"",onDismiss:e[2]||(e[2]=a=>j.value=null)},{default:n(()=>[r(p(j.value),1)]),_:1})):M("",!0),T.value&&!i.value?(d(),U("div",se,[o(t(F),{label:"Loading bucket..."})])):i.value?(d(),U(ne,{key:2},[o(t(J),{columns:4,gap:"0.75rem"},{default:n(()=>[o(t($),{label:"Objects",value:i.value.objectCount??0,tone:"info"},null,8,["value"]),o(t($),{label:"Size",value:O(i.value.totalSize),tone:"neutral"},null,8,["value"]),o(t($),{label:"Versioning",value:i.value.versioning?"Enabled":"Disabled",tone:i.value.versioning?"success":"neutral"},null,8,["value","tone"]),o(t($),{label:"Notifications",value:i.value.notifications??0,tone:(i.value.notifications??0)>0?"info":"neutral"},null,8,["value","tone"])]),_:1}),o(t(_),{variant:"outline"},{header:n(()=>[...e[12]||(e[12]=[m("strong",null,"Upload object",-1)])]),default:n(()=>[o(t(c),{direction:"vertical",gap:"0.5rem"},{default:n(()=>[o(t(S),{modelValue:w.value,"onUpdate:modelValue":e[3]||(e[3]=a=>w.value=a),placeholder:"object/key.txt",label:"Key"},null,8,["modelValue"]),o(t(S),{modelValue:h.value,"onUpdate:modelValue":e[4]||(e[4]=a=>h.value=a),placeholder:"text/plain",label:"Content-Type"},null,8,["modelValue"]),e[14]||(e[14]=m("label",{class:"muted",style:{"font-size":"0.875rem"}},"Body",-1)),Q(m("textarea",{"onUpdate:modelValue":e[5]||(e[5]=a=>x.value=a),rows:"4",style:{width:"100%","font-family":"var(--tree-font-mono, monospace)",padding:"0.5rem"},placeholder:"Hello, world!"},null,512),[[ee,x.value]]),o(t(c),{direction:"horizontal",justify:"flex-end"},{default:n(()=>[o(t(g),{size:"sm",loading:C.value,onClick:P},{default:n(()=>[...e[13]||(e[13]=[r("Upload",-1)])]),_:1},8,["loading"])]),_:1})]),_:1})]),_:1}),o(t(_),{variant:"outline"},{header:n(()=>[o(t(c),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between"},{default:n(()=>[m("strong",null,"Objects ("+p(y.value.length)+" · "+p(O(q.value))+")",1),o(t(c),{direction:"horizontal",gap:"0.5rem",align:"center"},{default:n(()=>[o(t(S),{modelValue:V.value,"onUpdate:modelValue":e[6]||(e[6]=a=>V.value=a),placeholder:"prefix filter",size:"sm",onKeyup:e[7]||(e[7]=le(a=>v(),["enter"]))},null,8,["modelValue"]),o(t(g),{size:"sm",variant:"ghost",onClick:e[8]||(e[8]=a=>v())},{default:n(()=>[...e[15]||(e[15]=[r("Apply",-1)])]),_:1})]),_:1})]),_:1})]),default:n(()=>[B.value?(d(),U("div",de,[o(t(F),{label:"Loading objects..."})])):y.value.length?(d(),k(t(ae),{key:2,columns:L,rows:y.value},{"cell-key":n(({row:a})=>[m("a",{href:G(String(a.key)),target:"_blank",rel:"noopener noreferrer",style:{"text-decoration":"none","font-weight":"500"}},p(a.key),9,ce)]),"cell-size":n(({row:a})=>[r(p(O(Number(a.size))),1)]),"cell-lastModified":n(({row:a})=>[r(p(A(a.lastModified)),1)]),"cell-actions":n(({row:a})=>[o(t(c),{direction:"horizontal",gap:"0.25rem",justify:"flex-end"},{default:n(()=>[m("a",{href:R(String(a.key)),target:"_blank",rel:"noopener noreferrer",style:{"text-decoration":"none"}},[o(t(g),{size:"sm",variant:"ghost"},{default:n(()=>[...e[16]||(e[16]=[r("Download",-1)])]),_:1})],8,fe),o(t(g),{size:"sm",variant:"ghost",tone:"danger",onClick:W=>H(String(a.key))},{default:n(()=>[...e[17]||(e[17]=[r(" Delete ",-1)])]),_:1},8,["onClick"])]),_:2},1024)]),_:1},8,["rows"])):(d(),k(t(te),{key:1,title:"No objects",description:"This bucket is empty (or the prefix filter excluded everything)."}))]),_:1})],64)):M("",!0)]),_:1}))}}),pe=E({__name:"BucketDetailPage",props:{bucketName:{}},setup(z){const N=re();function s(){N.push("/buckets")}return(K,f)=>(d(),k(ve,{"bucket-name":z.bucketName,onBack:s},null,8,["bucket-name"]))}});export{pe as default};
1
+ import{k as E,l as X,Y,e as k,U as t,t as c,Z as n,a as b,m as d,j as o,y as g,i as r,d as m,T as p,p as Z,f as M,G as I,g as U,s as F,x as $,w as J,E as S,_ as Q,X as ee,q as _,z as te,A as ae,$ as le,F as ne,c as oe,r as u,b as ie,W as re}from"./index-DGkmrq2b.js";const ue={style:{"font-size":"1.1rem"}},se={key:1,style:{display:"flex","justify-content":"center",padding:"2rem"}},de={key:0,style:{display:"flex","justify-content":"center",padding:"2rem"}},ce=["href"],fe=["href"],ve=E({__name:"BucketDetail",props:{bucketName:{}},emits:["back"],setup(z,{emit:N}){const s=z,K=N,f=oe(),i=u(null),y=u([]),V=u(""),T=u(!0),B=u(!1),j=u(null),w=u(""),x=u(""),h=u("text/plain"),C=u(!1),L=[{key:"key",label:"Key"},{key:"size",label:"Size",align:"right"},{key:"lastModified",label:"Modified"},{key:"actions",label:"",align:"right"}],q=ie(()=>y.value.reduce((l,e)=>l+(e.size||0),0));function O(l){if(l==null)return"—";if(l===0)return"0 B";const e=["B","KB","MB","GB","TB"],a=Math.floor(Math.log(l)/Math.log(1024));return`${(l/Math.pow(1024,a)).toFixed(a===0?0:1)} ${e[a]}`}function A(l){return l?new Date(l).toLocaleString():"—"}async function D(){try{i.value=await b.getBucket(s.bucketName),j.value=null}catch(l){j.value=l.message||"Failed to load bucket",i.value=null}finally{T.value=!1}}async function v(){B.value=!0;try{const l=await b.listBucketObjects(s.bucketName,{prefix:V.value||void 0,maxKeys:200});y.value=l.objects}catch(l){f.add({title:"Failed to load objects",description:l.message,variant:"danger"})}finally{B.value=!1}}function G(l){return b.bucketObjectContentUrl(s.bucketName,l,!1)}function R(l){return b.bucketObjectContentUrl(s.bucketName,l,!0)}async function H(l){if(confirm(`Delete object "${l}"?`))try{await b.deleteBucketObject(s.bucketName,l),f.add({title:"Object deleted",variant:"info"}),await v()}catch(e){f.add({title:"Failed to delete object",description:e.message,variant:"danger"})}}async function P(){if(!w.value||!x.value){f.add({title:"Key and body are required",variant:"warning"});return}C.value=!0;try{await b.putBucketObject(s.bucketName,{key:w.value,body:x.value,contentType:h.value||void 0}),f.add({title:"Object uploaded",variant:"info"}),w.value="",x.value="",await v(),await D()}catch(l){f.add({title:"Failed to upload object",description:l.message,variant:"danger"})}finally{C.value=!1}}return X(()=>{D(),v()}),Y(()=>s.bucketName,()=>{D(),v()}),(l,e)=>(d(),k(t(c),{direction:"vertical",gap:"1rem"},{default:n(()=>[o(t(c),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between"},{default:n(()=>[o(t(c),{direction:"horizontal",gap:"0.5rem",align:"center"},{default:n(()=>{var a;return[o(t(g),{size:"sm",variant:"ghost",onClick:e[0]||(e[0]=W=>K("back"))},{default:n(()=>[...e[9]||(e[9]=[r("← Buckets",-1)])]),_:1}),m("strong",ue,p(z.bucketName),1),(a=i.value)!=null&&a.versioning?(d(),k(t(Z),{key:0,tone:"info",variant:"soft"},{default:n(()=>[...e[10]||(e[10]=[r("Versioning",-1)])]),_:1})):M("",!0)]}),_:1}),o(t(g),{size:"sm",variant:"ghost",loading:B.value,onClick:e[1]||(e[1]=a=>v())},{default:n(()=>[...e[11]||(e[11]=[r("Refresh",-1)])]),_:1},8,["loading"])]),_:1}),j.value?(d(),k(t(I),{key:0,variant:"danger",dismissible:"",onDismiss:e[2]||(e[2]=a=>j.value=null)},{default:n(()=>[r(p(j.value),1)]),_:1})):M("",!0),T.value&&!i.value?(d(),U("div",se,[o(t(F),{label:"Loading bucket..."})])):i.value?(d(),U(ne,{key:2},[o(t(J),{columns:4,gap:"0.75rem"},{default:n(()=>[o(t($),{label:"Objects",value:i.value.objectCount??0,tone:"info"},null,8,["value"]),o(t($),{label:"Size",value:O(i.value.totalSize),tone:"neutral"},null,8,["value"]),o(t($),{label:"Versioning",value:i.value.versioning?"Enabled":"Disabled",tone:i.value.versioning?"success":"neutral"},null,8,["value","tone"]),o(t($),{label:"Notifications",value:i.value.notifications??0,tone:(i.value.notifications??0)>0?"info":"neutral"},null,8,["value","tone"])]),_:1}),o(t(_),{variant:"outline"},{header:n(()=>[...e[12]||(e[12]=[m("strong",null,"Upload object",-1)])]),default:n(()=>[o(t(c),{direction:"vertical",gap:"0.5rem"},{default:n(()=>[o(t(S),{modelValue:w.value,"onUpdate:modelValue":e[3]||(e[3]=a=>w.value=a),placeholder:"object/key.txt",label:"Key"},null,8,["modelValue"]),o(t(S),{modelValue:h.value,"onUpdate:modelValue":e[4]||(e[4]=a=>h.value=a),placeholder:"text/plain",label:"Content-Type"},null,8,["modelValue"]),e[14]||(e[14]=m("label",{class:"muted",style:{"font-size":"0.875rem"}},"Body",-1)),Q(m("textarea",{"onUpdate:modelValue":e[5]||(e[5]=a=>x.value=a),rows:"4",style:{width:"100%","font-family":"var(--tree-font-mono, monospace)",padding:"0.5rem"},placeholder:"Hello, world!"},null,512),[[ee,x.value]]),o(t(c),{direction:"horizontal",justify:"flex-end"},{default:n(()=>[o(t(g),{size:"sm",loading:C.value,onClick:P},{default:n(()=>[...e[13]||(e[13]=[r("Upload",-1)])]),_:1},8,["loading"])]),_:1})]),_:1})]),_:1}),o(t(_),{variant:"outline"},{header:n(()=>[o(t(c),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between"},{default:n(()=>[m("strong",null,"Objects ("+p(y.value.length)+" · "+p(O(q.value))+")",1),o(t(c),{direction:"horizontal",gap:"0.5rem",align:"center"},{default:n(()=>[o(t(S),{modelValue:V.value,"onUpdate:modelValue":e[6]||(e[6]=a=>V.value=a),placeholder:"prefix filter",size:"sm",onKeyup:e[7]||(e[7]=le(a=>v(),["enter"]))},null,8,["modelValue"]),o(t(g),{size:"sm",variant:"ghost",onClick:e[8]||(e[8]=a=>v())},{default:n(()=>[...e[15]||(e[15]=[r("Apply",-1)])]),_:1})]),_:1})]),_:1})]),default:n(()=>[B.value?(d(),U("div",de,[o(t(F),{label:"Loading objects..."})])):y.value.length?(d(),k(t(ae),{key:2,columns:L,rows:y.value},{"cell-key":n(({row:a})=>[m("a",{href:G(String(a.key)),target:"_blank",rel:"noopener noreferrer",style:{"text-decoration":"none","font-weight":"500"}},p(a.key),9,ce)]),"cell-size":n(({row:a})=>[r(p(O(Number(a.size))),1)]),"cell-lastModified":n(({row:a})=>[r(p(A(a.lastModified)),1)]),"cell-actions":n(({row:a})=>[o(t(c),{direction:"horizontal",gap:"0.25rem",justify:"flex-end"},{default:n(()=>[m("a",{href:R(String(a.key)),target:"_blank",rel:"noopener noreferrer",style:{"text-decoration":"none"}},[o(t(g),{size:"sm",variant:"ghost"},{default:n(()=>[...e[16]||(e[16]=[r("Download",-1)])]),_:1})],8,fe),o(t(g),{size:"sm",variant:"ghost",tone:"danger",onClick:W=>H(String(a.key))},{default:n(()=>[...e[17]||(e[17]=[r(" Delete ",-1)])]),_:1},8,["onClick"])]),_:2},1024)]),_:1},8,["rows"])):(d(),k(t(te),{key:1,title:"No objects",description:"This bucket is empty (or the prefix filter excluded everything)."}))]),_:1})],64)):M("",!0)]),_:1}))}}),pe=E({__name:"BucketDetailPage",props:{bucketName:{}},setup(z){const N=re();function s(){N.push("/buckets")}return(K,f)=>(d(),k(ve,{"bucket-name":z.bucketName,onBack:s},null,8,["bucket-name"]))}});export{pe as default};
@@ -1 +1 @@
1
- import{k as x,W as V,l as T,o as D,m as o,e as u,U as n,t as z,Z as a,j as l,w as I,x as p,G as O,i as c,T as r,f as U,q as L,g as C,s as q,z as E,A as F,y as G,p as b,R as P,u as A,d as _,a0 as K,r as m,b as S,a as j}from"./index-BP9zQ9L-.js";const W={key:0,style:{display:"flex","justify-content":"center",padding:"2rem"}},Z=["onClick"],H={key:1,class:"muted",style:{"font-size":"0.75rem"}},J=x({__name:"BucketsView",setup(R){const y=V(),i=m([]),h=m({}),d=m(!0),v=m(null);let g=null;const M=[{key:"name",label:"Bucket"},{key:"service",label:"Service"},{key:"objectCount",label:"Objects",align:"right"},{key:"totalSize",label:"Size",align:"right"},{key:"versioning",label:"Versioning"},{key:"notifications",label:"Notifications",align:"right"},{key:"actions",label:"",align:"right"}],N=S(()=>i.value.map(t=>({...t,service:h.value[t.name]||""}))),k=S(()=>({buckets:i.value.length,objects:i.value.reduce((t,s)=>t+(s.objectCount||0),0),size:i.value.reduce((t,s)=>t+(s.totalSize||0),0)}));function B(t){if(t==null)return"—";if(t===0)return"0 B";const s=["B","KB","MB","GB","TB"],e=Math.floor(Math.log(t)/Math.log(1024));return`${(t/Math.pow(1024,e)).toFixed(e===0?0:1)} ${s[e]}`}async function $(){try{const[t,s]=await Promise.all([j.listBuckets(),j.listResourceOwners().catch(()=>({tables:[],queues:[],topics:[],buckets:[]}))]);i.value=t;const e={};for(const f of s.buckets||[])e[f.name]=f.service;h.value=e,v.value=null}catch(t){v.value=t.message||"Failed to load buckets"}finally{d.value=!1}}function w(t){y.push(`/buckets/${encodeURIComponent(t)}`)}return T(()=>{$(),g=window.setInterval($,1e4)}),D(()=>{g&&window.clearInterval(g)}),(t,s)=>(o(),u(n(z),{direction:"vertical",gap:"1.25rem"},{default:a(()=>[l(n(I),{columns:3,gap:"1rem"},{default:a(()=>[l(n(p),{label:"Buckets",value:k.value.buckets,tone:"info",loading:d.value},null,8,["value","loading"]),l(n(p),{label:"Objects",value:k.value.objects,tone:"success",loading:d.value},null,8,["value","loading"]),l(n(p),{label:"Total size",value:B(k.value.size),tone:"neutral",loading:d.value},null,8,["value","loading"])]),_:1}),v.value?(o(),u(n(O),{key:0,variant:"danger",dismissible:"",onDismiss:s[0]||(s[0]=e=>v.value=null)},{default:a(()=>[c(r(v.value),1)]),_:1})):U("",!0),l(n(L),{variant:"outline"},{header:a(()=>[l(n(z),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between"},{default:a(()=>[...s[1]||(s[1]=[_("strong",null,"S3 Buckets",-1),_("span",{class:"muted"},"Refreshes every 10s",-1)])]),_:1})]),default:a(()=>[d.value?(o(),C("div",W,[l(n(q),{label:"Loading buckets..."})])):i.value.length?(o(),u(n(F),{key:2,columns:M,rows:N.value},{"cell-name":a(({row:e})=>[_("a",{href:"#",style:{"text-decoration":"none","font-weight":"600"},onClick:K(f=>w(String(e.name)),["prevent"])},r(e.name),9,Z)]),"cell-service":a(({row:e})=>[e.service?(o(),u(n(P),{key:0,to:`/services/${encodeURIComponent(String(e.service))}`,style:{"text-decoration":"none"}},{default:a(()=>[l(n(A),{size:"sm",variant:"soft",clickable:""},{default:a(()=>[c(r(e.service),1)]),_:2},1024)]),_:2},1032,["to"])):(o(),C("span",H,"unmanaged"))]),"cell-objectCount":a(({row:e})=>[l(n(b),{tone:"info",variant:"soft"},{default:a(()=>[c(r(e.objectCount??0),1)]),_:2},1024)]),"cell-totalSize":a(({row:e})=>[c(r(B(e.totalSize)),1)]),"cell-versioning":a(({row:e})=>[l(n(b),{tone:e.versioning?"success":"neutral",variant:"soft"},{default:a(()=>[c(r(e.versioning?"Enabled":"Disabled"),1)]),_:2},1032,["tone"])]),"cell-notifications":a(({row:e})=>[l(n(b),{tone:Number(e.notifications)>0?"info":"neutral",variant:"soft"},{default:a(()=>[c(r(e.notifications??0),1)]),_:2},1032,["tone"])]),"cell-actions":a(({row:e})=>[l(n(G),{size:"sm",variant:"ghost",onClick:f=>w(String(e.name))},{default:a(()=>[...s[2]||(s[2]=[c(" Open ",-1)])]),_:1},8,["onClick"])]),_:1},8,["rows"])):(o(),u(n(E),{key:1,title:"No buckets found",description:"Register a microservice that defines S3 resources or create buckets directly in LocalStack."}))]),_:1})]),_:1}))}}),X=x({__name:"BucketsPage",setup(R){return(y,i)=>(o(),u(J))}});export{X as default};
1
+ import{k as x,W as V,l as T,o as D,m as o,e as u,U as n,t as z,Z as a,j as l,w as I,x as p,G as O,i as c,T as r,f as U,q as L,g as C,s as q,z as E,A as F,y as G,p as b,R as P,u as A,d as _,a0 as K,r as m,b as S,a as j}from"./index-DGkmrq2b.js";const W={key:0,style:{display:"flex","justify-content":"center",padding:"2rem"}},Z=["onClick"],H={key:1,class:"muted",style:{"font-size":"0.75rem"}},J=x({__name:"BucketsView",setup(R){const y=V(),i=m([]),h=m({}),d=m(!0),v=m(null);let g=null;const M=[{key:"name",label:"Bucket"},{key:"service",label:"Service"},{key:"objectCount",label:"Objects",align:"right"},{key:"totalSize",label:"Size",align:"right"},{key:"versioning",label:"Versioning"},{key:"notifications",label:"Notifications",align:"right"},{key:"actions",label:"",align:"right"}],N=S(()=>i.value.map(t=>({...t,service:h.value[t.name]||""}))),k=S(()=>({buckets:i.value.length,objects:i.value.reduce((t,s)=>t+(s.objectCount||0),0),size:i.value.reduce((t,s)=>t+(s.totalSize||0),0)}));function B(t){if(t==null)return"—";if(t===0)return"0 B";const s=["B","KB","MB","GB","TB"],e=Math.floor(Math.log(t)/Math.log(1024));return`${(t/Math.pow(1024,e)).toFixed(e===0?0:1)} ${s[e]}`}async function $(){try{const[t,s]=await Promise.all([j.listBuckets(),j.listResourceOwners().catch(()=>({tables:[],queues:[],topics:[],buckets:[]}))]);i.value=t;const e={};for(const f of s.buckets||[])e[f.name]=f.service;h.value=e,v.value=null}catch(t){v.value=t.message||"Failed to load buckets"}finally{d.value=!1}}function w(t){y.push(`/buckets/${encodeURIComponent(t)}`)}return T(()=>{$(),g=window.setInterval($,1e4)}),D(()=>{g&&window.clearInterval(g)}),(t,s)=>(o(),u(n(z),{direction:"vertical",gap:"1.25rem"},{default:a(()=>[l(n(I),{columns:3,gap:"1rem"},{default:a(()=>[l(n(p),{label:"Buckets",value:k.value.buckets,tone:"info",loading:d.value},null,8,["value","loading"]),l(n(p),{label:"Objects",value:k.value.objects,tone:"success",loading:d.value},null,8,["value","loading"]),l(n(p),{label:"Total size",value:B(k.value.size),tone:"neutral",loading:d.value},null,8,["value","loading"])]),_:1}),v.value?(o(),u(n(O),{key:0,variant:"danger",dismissible:"",onDismiss:s[0]||(s[0]=e=>v.value=null)},{default:a(()=>[c(r(v.value),1)]),_:1})):U("",!0),l(n(L),{variant:"outline"},{header:a(()=>[l(n(z),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between"},{default:a(()=>[...s[1]||(s[1]=[_("strong",null,"S3 Buckets",-1),_("span",{class:"muted"},"Refreshes every 10s",-1)])]),_:1})]),default:a(()=>[d.value?(o(),C("div",W,[l(n(q),{label:"Loading buckets..."})])):i.value.length?(o(),u(n(F),{key:2,columns:M,rows:N.value},{"cell-name":a(({row:e})=>[_("a",{href:"#",style:{"text-decoration":"none","font-weight":"600"},onClick:K(f=>w(String(e.name)),["prevent"])},r(e.name),9,Z)]),"cell-service":a(({row:e})=>[e.service?(o(),u(n(P),{key:0,to:`/services/${encodeURIComponent(String(e.service))}`,style:{"text-decoration":"none"}},{default:a(()=>[l(n(A),{size:"sm",variant:"soft",clickable:""},{default:a(()=>[c(r(e.service),1)]),_:2},1024)]),_:2},1032,["to"])):(o(),C("span",H,"unmanaged"))]),"cell-objectCount":a(({row:e})=>[l(n(b),{tone:"info",variant:"soft"},{default:a(()=>[c(r(e.objectCount??0),1)]),_:2},1024)]),"cell-totalSize":a(({row:e})=>[c(r(B(e.totalSize)),1)]),"cell-versioning":a(({row:e})=>[l(n(b),{tone:e.versioning?"success":"neutral",variant:"soft"},{default:a(()=>[c(r(e.versioning?"Enabled":"Disabled"),1)]),_:2},1032,["tone"])]),"cell-notifications":a(({row:e})=>[l(n(b),{tone:Number(e.notifications)>0?"info":"neutral",variant:"soft"},{default:a(()=>[c(r(e.notifications??0),1)]),_:2},1032,["tone"])]),"cell-actions":a(({row:e})=>[l(n(G),{size:"sm",variant:"ghost",onClick:f=>w(String(e.name))},{default:a(()=>[...s[2]||(s[2]=[c(" Open ",-1)])]),_:1},8,["onClick"])]),_:1},8,["rows"])):(o(),u(n(E),{key:1,title:"No buckets found",description:"Register a microservice that defines S3 resources or create buckets directly in LocalStack."}))]),_:1})]),_:1}))}}),X=x({__name:"BucketsPage",setup(R){return(y,i)=>(o(),u(J))}});export{X as default};
@@ -1 +1 @@
1
- import{k as K,l as j,o as q,m as n,e as i,U as s,t as C,Z as a,j as o,w as F,x as $,G as W,i as r,T as u,f,q as H,g as y,s as Z,z as A,A as J,y as Q,u as p,p as R,R as X,d as S,E as Y,r as g,b as T,a as L,W as ee}from"./index-BP9zQ9L-.js";const te={key:0,style:{display:"flex","justify-content":"center",padding:"2rem"}},se=["onClick"],ae={key:1},ne={class:"muted mono",style:{"font-size":"0.75rem"}},le={key:1,class:"muted",style:{"font-size":"0.75rem"}},ie={key:1,class:"muted",style:{"font-size":"0.75rem"}},oe={key:1,class:"muted",style:{"font-size":"0.75rem"}},re=K({__name:"DynamoTablesList",emits:["open"],setup(U,{emit:N}){const D=N,d=g([]),b=g([]),w=g({}),c=g(!0),k=g(null),x=g("");let z=null;const M=[{key:"name",label:"Table"},{key:"service",label:"Service"},{key:"status",label:"Status"},{key:"itemCount",label:"Items",align:"right"},{key:"seed",label:"Seed"},{key:"features",label:"Features"},{key:"actions",label:"",align:"right"}],I=T(()=>{const l=d.value.map(e=>{var P,V;const t=(P=e.keySchema.find(_=>_.KeyType==="HASH"))==null?void 0:P.AttributeName,m=(V=e.keySchema.find(_=>_.KeyType==="RANGE"))==null?void 0:V.AttributeName,h=m?`PK: ${t} · SK: ${m}`:`PK: ${t??"—"}`,G=b.value.find(_=>_.tableName===e.name);return{name:e.name,status:e.status,itemCount:e.itemCount||0,keyDescriptor:h,billingMode:e.billingMode,ttlOn:e.ttl.enabled,streamOn:e.streamEnabled,hasGsi:e.hasGsi,hasLsi:e.hasLsi,service:w.value[e.name]||"",seedItemCount:G?G.itemCount:null,exists:!0}});for(const e of b.value)!e.tableExists&&!l.some(t=>t.name===e.tableName)&&l.push({name:e.tableName,status:"PENDING",itemCount:0,keyDescriptor:"—",ttlOn:!1,streamOn:!1,hasGsi:!1,hasLsi:!1,service:w.value[e.tableName]||"",seedItemCount:e.itemCount,exists:!1});return l.sort((e,t)=>e.name.localeCompare(t.name))}),B=T(()=>{const l=x.value.trim().toLowerCase();return l?I.value.filter(e=>e.name.toLowerCase().includes(l)||(e.service||"").toLowerCase().includes(l)):I.value}),v=T(()=>({tables:d.value.length,items:d.value.reduce((l,e)=>l+(e.itemCount||0),0),warnings:d.value.reduce((l,e)=>{var t;return l+(((t=e.warnings)==null?void 0:t.length)||0)},0),seedsPending:b.value.filter(l=>!l.tableExists).length}));async function E(){try{const[l,e,t]=await Promise.all([L.listDynamoTables(),L.listSeeds().catch(()=>({seedsDir:"",entries:[]})),L.listResourceOwners().catch(()=>({tables:[],queues:[],topics:[],buckets:[]}))]);d.value=l.tables,b.value=e.entries;const m={};for(const h of t.tables)m[h.name]=h.service;w.value=m,k.value=null}catch(l){k.value=l.message||"Failed to load DynamoDB tables"}finally{c.value=!1}}function O(l){l.exists&&D("open",l.name)}return j(()=>{E(),z=window.setInterval(E,15e3)}),q(()=>{z&&window.clearInterval(z)}),(l,e)=>(n(),i(s(C),{direction:"vertical",gap:"1.25rem"},{default:a(()=>[o(s(F),{columns:4,gap:"1rem"},{default:a(()=>[o(s($),{label:"Tables",value:v.value.tables,tone:"info",loading:c.value},null,8,["value","loading"]),o(s($),{label:"Total items",value:v.value.items,tone:"success",loading:c.value},null,8,["value","loading"]),o(s($),{label:"Seeds pending",value:v.value.seedsPending,tone:v.value.seedsPending>0?"warning":"neutral",loading:c.value},null,8,["value","tone","loading"]),o(s($),{label:"Warnings",value:v.value.warnings,tone:v.value.warnings>0?"warning":"neutral",loading:c.value},null,8,["value","tone","loading"])]),_:1}),k.value?(n(),i(s(W),{key:0,variant:"danger",dismissible:"",onDismiss:e[0]||(e[0]=t=>k.value=null)},{default:a(()=>[r(u(k.value),1)]),_:1})):f("",!0),o(s(H),{variant:"outline"},{header:a(()=>[o(s(C),{direction:"horizontal",justify:"space-between",align:"center",gap:"1rem"},{default:a(()=>[e[3]||(e[3]=S("strong",null,"DynamoDB tables",-1)),o(s(C),{direction:"horizontal",align:"center",gap:"1rem"},{default:a(()=>[o(s(Y),{modelValue:x.value,"onUpdate:modelValue":e[1]||(e[1]=t=>x.value=t),placeholder:"Filter tables...",style:{"min-width":"16rem"}},null,8,["modelValue"]),e[2]||(e[2]=S("span",{class:"muted",style:{"font-size":"0.75rem"}}," Rows with reduced opacity exist only as a seed file ",-1))]),_:1})]),_:1})]),default:a(()=>[c.value?(n(),y("div",te,[o(s(Z),{label:"Loading tables..."})])):I.value.length?B.value.length?(n(),i(s(J),{key:3,columns:M,rows:B.value,"row-class":t=>t.exists?"":"dim-row"},{"cell-name":a(({row:t})=>[o(s(C),{direction:"vertical",gap:"0.125rem"},{default:a(()=>[t.exists?(n(),y("strong",{key:0,style:{cursor:"pointer","text-decoration":"underline","text-decoration-style":"dotted","text-underline-offset":"3px"},onClick:m=>O(t)},u(t.name),9,se)):(n(),y("strong",ae,u(t.name),1)),S("span",ne,u(t.keyDescriptor),1)]),_:2},1024)]),"cell-service":a(({row:t})=>[t.service?(n(),i(s(X),{key:0,to:`/services/${encodeURIComponent(String(t.service))}`,style:{"text-decoration":"none"}},{default:a(()=>[o(s(p),{size:"sm",variant:"soft",clickable:""},{default:a(()=>[r(u(t.service),1)]),_:2},1024)]),_:2},1032,["to"])):(n(),y("span",le,"—"))]),"cell-status":a(({row:t})=>[t.exists?(n(),i(s(R),{key:0,tone:t.status==="ACTIVE"?"success":"warning",variant:"soft"},{default:a(()=>[r(u(t.status||"UNKNOWN"),1)]),_:2},1032,["tone"])):(n(),i(s(R),{key:1,tone:"warning",variant:"outline"},{default:a(()=>[...e[4]||(e[4]=[r("Not created",-1)])]),_:1}))]),"cell-itemCount":a(({row:t})=>[r(u(t.exists?t.itemCount:"—"),1)]),"cell-seed":a(({row:t})=>[t.seedItemCount!==null?(n(),i(s(R),{key:0,tone:t.exists?"info":"warning",variant:"soft"},{default:a(()=>[r(u(t.seedItemCount)+" seeded item"+u(t.seedItemCount===1?"":"s"),1)]),_:2},1032,["tone"])):(n(),y("span",ie,"no seed"))]),"cell-features":a(({row:t})=>[o(s(C),{direction:"horizontal",gap:"0.25rem",wrap:""},{default:a(()=>[t.billingMode?(n(),i(s(p),{key:0,size:"sm",variant:"soft"},{default:a(()=>[r(u(t.billingMode),1)]),_:2},1024)):f("",!0),t.ttlOn?(n(),i(s(p),{key:1,size:"sm",variant:"solid"},{default:a(()=>[...e[5]||(e[5]=[r("TTL",-1)])]),_:1})):f("",!0),t.streamOn?(n(),i(s(p),{key:2,size:"sm",variant:"solid"},{default:a(()=>[...e[6]||(e[6]=[r("Streams",-1)])]),_:1})):f("",!0),t.hasGsi?(n(),i(s(p),{key:3,size:"sm",variant:"soft"},{default:a(()=>[...e[7]||(e[7]=[r("GSI",-1)])]),_:1})):f("",!0),t.hasLsi?(n(),i(s(p),{key:4,size:"sm",variant:"soft"},{default:a(()=>[...e[8]||(e[8]=[r("LSI",-1)])]),_:1})):f("",!0)]),_:2},1024)]),"cell-actions":a(({row:t})=>[t.exists?(n(),i(s(Q),{key:0,size:"sm",variant:"soft",onClick:m=>O(t)},{default:a(()=>[...e[9]||(e[9]=[r(" Explore ",-1)])]),_:1},8,["onClick"])):(n(),y("span",oe," Register service to provision "))]),_:1},8,["rows","row-class"])):(n(),i(s(A),{key:2,title:"No matching tables",description:`No tables match "${x.value}".`},null,8,["description"])):(n(),i(s(A),{key:1,title:"No DynamoDB tables",description:"Register a microservice with DynamoDB resources or drop a seed file into the seeds directory."}))]),_:1})]),_:1}))}}),de=K({__name:"DynamoPage",setup(U){const N=ee();function D(d){N.push(`/dynamo/${encodeURIComponent(d)}`)}return(d,b)=>(n(),i(re,{onOpen:D}))}});export{de as default};
1
+ import{k as K,l as j,o as q,m as n,e as i,U as s,t as C,Z as a,j as o,w as F,x as $,G as W,i as r,T as u,f,q as H,g as y,s as Z,z as A,A as J,y as Q,u as p,p as R,R as X,d as S,E as Y,r as g,b as T,a as L,W as ee}from"./index-DGkmrq2b.js";const te={key:0,style:{display:"flex","justify-content":"center",padding:"2rem"}},se=["onClick"],ae={key:1},ne={class:"muted mono",style:{"font-size":"0.75rem"}},le={key:1,class:"muted",style:{"font-size":"0.75rem"}},ie={key:1,class:"muted",style:{"font-size":"0.75rem"}},oe={key:1,class:"muted",style:{"font-size":"0.75rem"}},re=K({__name:"DynamoTablesList",emits:["open"],setup(U,{emit:N}){const D=N,d=g([]),b=g([]),w=g({}),c=g(!0),k=g(null),x=g("");let z=null;const M=[{key:"name",label:"Table"},{key:"service",label:"Service"},{key:"status",label:"Status"},{key:"itemCount",label:"Items",align:"right"},{key:"seed",label:"Seed"},{key:"features",label:"Features"},{key:"actions",label:"",align:"right"}],I=T(()=>{const l=d.value.map(e=>{var P,V;const t=(P=e.keySchema.find(_=>_.KeyType==="HASH"))==null?void 0:P.AttributeName,m=(V=e.keySchema.find(_=>_.KeyType==="RANGE"))==null?void 0:V.AttributeName,h=m?`PK: ${t} · SK: ${m}`:`PK: ${t??"—"}`,G=b.value.find(_=>_.tableName===e.name);return{name:e.name,status:e.status,itemCount:e.itemCount||0,keyDescriptor:h,billingMode:e.billingMode,ttlOn:e.ttl.enabled,streamOn:e.streamEnabled,hasGsi:e.hasGsi,hasLsi:e.hasLsi,service:w.value[e.name]||"",seedItemCount:G?G.itemCount:null,exists:!0}});for(const e of b.value)!e.tableExists&&!l.some(t=>t.name===e.tableName)&&l.push({name:e.tableName,status:"PENDING",itemCount:0,keyDescriptor:"—",ttlOn:!1,streamOn:!1,hasGsi:!1,hasLsi:!1,service:w.value[e.tableName]||"",seedItemCount:e.itemCount,exists:!1});return l.sort((e,t)=>e.name.localeCompare(t.name))}),B=T(()=>{const l=x.value.trim().toLowerCase();return l?I.value.filter(e=>e.name.toLowerCase().includes(l)||(e.service||"").toLowerCase().includes(l)):I.value}),v=T(()=>({tables:d.value.length,items:d.value.reduce((l,e)=>l+(e.itemCount||0),0),warnings:d.value.reduce((l,e)=>{var t;return l+(((t=e.warnings)==null?void 0:t.length)||0)},0),seedsPending:b.value.filter(l=>!l.tableExists).length}));async function E(){try{const[l,e,t]=await Promise.all([L.listDynamoTables(),L.listSeeds().catch(()=>({seedsDir:"",entries:[]})),L.listResourceOwners().catch(()=>({tables:[],queues:[],topics:[],buckets:[]}))]);d.value=l.tables,b.value=e.entries;const m={};for(const h of t.tables)m[h.name]=h.service;w.value=m,k.value=null}catch(l){k.value=l.message||"Failed to load DynamoDB tables"}finally{c.value=!1}}function O(l){l.exists&&D("open",l.name)}return j(()=>{E(),z=window.setInterval(E,15e3)}),q(()=>{z&&window.clearInterval(z)}),(l,e)=>(n(),i(s(C),{direction:"vertical",gap:"1.25rem"},{default:a(()=>[o(s(F),{columns:4,gap:"1rem"},{default:a(()=>[o(s($),{label:"Tables",value:v.value.tables,tone:"info",loading:c.value},null,8,["value","loading"]),o(s($),{label:"Total items",value:v.value.items,tone:"success",loading:c.value},null,8,["value","loading"]),o(s($),{label:"Seeds pending",value:v.value.seedsPending,tone:v.value.seedsPending>0?"warning":"neutral",loading:c.value},null,8,["value","tone","loading"]),o(s($),{label:"Warnings",value:v.value.warnings,tone:v.value.warnings>0?"warning":"neutral",loading:c.value},null,8,["value","tone","loading"])]),_:1}),k.value?(n(),i(s(W),{key:0,variant:"danger",dismissible:"",onDismiss:e[0]||(e[0]=t=>k.value=null)},{default:a(()=>[r(u(k.value),1)]),_:1})):f("",!0),o(s(H),{variant:"outline"},{header:a(()=>[o(s(C),{direction:"horizontal",justify:"space-between",align:"center",gap:"1rem"},{default:a(()=>[e[3]||(e[3]=S("strong",null,"DynamoDB tables",-1)),o(s(C),{direction:"horizontal",align:"center",gap:"1rem"},{default:a(()=>[o(s(Y),{modelValue:x.value,"onUpdate:modelValue":e[1]||(e[1]=t=>x.value=t),placeholder:"Filter tables...",style:{"min-width":"16rem"}},null,8,["modelValue"]),e[2]||(e[2]=S("span",{class:"muted",style:{"font-size":"0.75rem"}}," Rows with reduced opacity exist only as a seed file ",-1))]),_:1})]),_:1})]),default:a(()=>[c.value?(n(),y("div",te,[o(s(Z),{label:"Loading tables..."})])):I.value.length?B.value.length?(n(),i(s(J),{key:3,columns:M,rows:B.value,"row-class":t=>t.exists?"":"dim-row"},{"cell-name":a(({row:t})=>[o(s(C),{direction:"vertical",gap:"0.125rem"},{default:a(()=>[t.exists?(n(),y("strong",{key:0,style:{cursor:"pointer","text-decoration":"underline","text-decoration-style":"dotted","text-underline-offset":"3px"},onClick:m=>O(t)},u(t.name),9,se)):(n(),y("strong",ae,u(t.name),1)),S("span",ne,u(t.keyDescriptor),1)]),_:2},1024)]),"cell-service":a(({row:t})=>[t.service?(n(),i(s(X),{key:0,to:`/services/${encodeURIComponent(String(t.service))}`,style:{"text-decoration":"none"}},{default:a(()=>[o(s(p),{size:"sm",variant:"soft",clickable:""},{default:a(()=>[r(u(t.service),1)]),_:2},1024)]),_:2},1032,["to"])):(n(),y("span",le,"—"))]),"cell-status":a(({row:t})=>[t.exists?(n(),i(s(R),{key:0,tone:t.status==="ACTIVE"?"success":"warning",variant:"soft"},{default:a(()=>[r(u(t.status||"UNKNOWN"),1)]),_:2},1032,["tone"])):(n(),i(s(R),{key:1,tone:"warning",variant:"outline"},{default:a(()=>[...e[4]||(e[4]=[r("Not created",-1)])]),_:1}))]),"cell-itemCount":a(({row:t})=>[r(u(t.exists?t.itemCount:"—"),1)]),"cell-seed":a(({row:t})=>[t.seedItemCount!==null?(n(),i(s(R),{key:0,tone:t.exists?"info":"warning",variant:"soft"},{default:a(()=>[r(u(t.seedItemCount)+" seeded item"+u(t.seedItemCount===1?"":"s"),1)]),_:2},1032,["tone"])):(n(),y("span",ie,"no seed"))]),"cell-features":a(({row:t})=>[o(s(C),{direction:"horizontal",gap:"0.25rem",wrap:""},{default:a(()=>[t.billingMode?(n(),i(s(p),{key:0,size:"sm",variant:"soft"},{default:a(()=>[r(u(t.billingMode),1)]),_:2},1024)):f("",!0),t.ttlOn?(n(),i(s(p),{key:1,size:"sm",variant:"solid"},{default:a(()=>[...e[5]||(e[5]=[r("TTL",-1)])]),_:1})):f("",!0),t.streamOn?(n(),i(s(p),{key:2,size:"sm",variant:"solid"},{default:a(()=>[...e[6]||(e[6]=[r("Streams",-1)])]),_:1})):f("",!0),t.hasGsi?(n(),i(s(p),{key:3,size:"sm",variant:"soft"},{default:a(()=>[...e[7]||(e[7]=[r("GSI",-1)])]),_:1})):f("",!0),t.hasLsi?(n(),i(s(p),{key:4,size:"sm",variant:"soft"},{default:a(()=>[...e[8]||(e[8]=[r("LSI",-1)])]),_:1})):f("",!0)]),_:2},1024)]),"cell-actions":a(({row:t})=>[t.exists?(n(),i(s(Q),{key:0,size:"sm",variant:"soft",onClick:m=>O(t)},{default:a(()=>[...e[9]||(e[9]=[r(" Explore ",-1)])]),_:1},8,["onClick"])):(n(),y("span",oe," Register service to provision "))]),_:1},8,["rows","row-class"])):(n(),i(s(A),{key:2,title:"No matching tables",description:`No tables match "${x.value}".`},null,8,["description"])):(n(),i(s(A),{key:1,title:"No DynamoDB tables",description:"Register a microservice with DynamoDB resources or drop a seed file into the seeds directory."}))]),_:1})]),_:1}))}}),de=K({__name:"DynamoPage",setup(U){const N=ee();function D(d){N.push(`/dynamo/${encodeURIComponent(d)}`)}return(d,b)=>(n(),i(re,{onOpen:D}))}});export{de as default};